home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / jaq / dist / tbuf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-02  |  16.4 KB  |  664 lines

  1. /* 
  2.  * tbuf.c--
  3.  *
  4.  *    Routines to handle tape buffer stuff
  5.  *
  6.  * Copyright 1992 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/tbuf.c,v 1.0 91/01/07 18:02:37 mottsmth Exp $ SPRITE (Berkeley)";
  18. #endif /* not lint */
  19.  
  20. #include "jaquith.h"
  21.  
  22. #define MINFREEVOLS 2
  23. #define BUFSIZE 4096
  24.  
  25. extern int jDebug;            /* Internal debugging only */
  26. extern int syserr;            /* Our personal record of errno */
  27.  
  28. /*
  29.  * Layout for building tar headers
  30.  */
  31. #define TBLOCK 512
  32. #define NAMSIZ 100
  33. #define    TUNMLEN    32
  34. #define    TGNMLEN    32
  35. #define    PRFXLEN    155
  36. #define    TMAGIC        "ustar  "  /* 7 chars and a null */
  37. #define    LF_OLDNORMAL    '\0'    /* Normal disk file, Unix compat */
  38. #define    LF_NORMAL    '0'    /* Normal disk file */
  39. #define    LF_LINK        '1'    /* Link to previously dumped file */
  40. #define    LF_SYMLINK    '2'    /* Symbolic link */
  41. #define    LF_CHR        '3'    /* Character special file */
  42. #define    LF_BLK        '4'    /* Block special file */
  43. #define    LF_DIR        '5'    /* Directory */
  44. #define    LF_FIFO        '6'    /* FIFO special file */
  45. #define    LF_CONTIG    '7'    /* Contiguous file */
  46. #define    LF_RMTLINK    'R'    /* Sprite Remote link */
  47.  
  48. typedef struct THdr {
  49.     char name[NAMSIZ];        /* file name */
  50.     char mode[8];             /* protection type */
  51.     char uid[8];              /* user id # */
  52.     char gid[8];              /* group id # */
  53.     char size[12];            /* size in bytes */
  54.     char mtime[12];           /* last modified time */
  55.     char chksum[8];           /* checksum with this field == spaces */
  56.     char linkflag;            /* file type */
  57.     char linkname[NAMSIZ];    /* target file name if this is a sym link */
  58.     char magic[6];            /* TMAGIC */
  59.     char version[2];          /* "00" */
  60.     char uname[TUNMLEN];      /* user name */
  61.     char gname[TGNMLEN];      /* group name */
  62.     char devmajor[8];         /* major device byte if this is a device */
  63.     char devminor[8];         /* minor device byte */
  64.     char prefix[PRFXLEN];     /* prefix to file name */
  65. } THdr;
  66.  
  67.  
  68. /*
  69.  *----------------------------------------------------------------------
  70.  *
  71.  * TBuf_Pad --
  72.  *
  73.  *    Pad the buffer to the specified unit.
  74.  *
  75.  * Results:
  76.  *    Returns # of bytes written.
  77.  *
  78.  * Side effects:
  79.  *    None.
  80.  *
  81.  * Note:
  82.  *      This is written so it can pad out to a block larger than
  83.  *      T_TBLOCK, even though this isn't needed presently.
  84.  *
  85.  *----------------------------------------------------------------------
  86.  */
  87.  
  88. int
  89. TBuf_Pad(tBufStream, len, blockSize)
  90.     int tBufStream;           /* output file descriptor */
  91.     int len;                  /* current size of buffer */
  92.     int blockSize;            /* desired blocksize */
  93. {
  94.     char nullBuf[T_TBLOCK];
  95.     char null = '\0';
  96.     int left;
  97.     int total;
  98.  
  99.     total = left = blockSize - (len % blockSize);
  100.     if (total == blockSize) {
  101.     return 0;
  102.     }
  103.     strncpy(nullBuf, &null, sizeof(nullBuf));
  104.  
  105.     while (left > 0) {
  106.     len = (left > sizeof(nullBuf)) ? sizeof(nullBuf) : left;
  107.     if ((len=write(tBufStream, nullBuf, len)) < 1) {
  108.         syserr = errno;
  109.         return T_IOFAILED;
  110.     }
  111.         left -= len;
  112.     }
  113.  
  114.     return total;
  115.  
  116. }
  117.  
  118.  
  119. /*
  120.  *----------------------------------------------------------------------
  121.  *
  122.  * TBuf_Open --
  123.  *
  124.  *    Open Tape buffer.
  125.  *
  126.  * Results:
  127.  *    file descriptor of open buffer file.
  128.  *
  129.  * Side effects:
  130.  *    None.
  131.  *
  132.  * Note:
  133.  *      A return code of T_SUCCESS just means the attempt was ok.
  134.  *      Still need to check stream ptr to see if file was there.
  135.  *
  136.  *----------------------------------------------------------------------
  137.  */
  138.  
  139. int
  140. TBuf_Open(path, tBufId, tBufStreamPtr, tHdrStreamPtr, mode) 
  141.     char *path;               /* path to tape buffer file */
  142.     int tBufId;               /* tBuf number (name) of file */
  143.     int *tBufStreamPtr;       /* receiving descriptor for tbuf */
  144.     int *tHdrStreamPtr;       /* receiving descriptor for hdr */
  145.     int mode;                 /* open mode: O_RDONLY, O_WRONLY, O_RDWR */
  146. {
  147.     char fullPath[T_MAXPATHLEN];
  148.     int pathLen;
  149.  
  150.     strcpy(fullPath, path);
  151.     strcat(fullPath, "/");
  152.     pathLen = strlen(fullPath);
  153.     sprintf(fullPath+pathLen, "tbuf.%d%c", tBufId, '\0');
  154.  
  155.     if ((*tBufStreamPtr=open(fullPath, mode, 0)) < 0) {
  156.     /*
  157.      * File doesn't exist; we have to make it
  158.      */
  159.     if (errno == ENOENT) {
  160.         if (mode & (O_RDWR | O_WRONLY)) {
  161.         if ((*tBufStreamPtr=open(fullPath, mode+O_CREAT, 0600)) < 0) {
  162.             syserr = errno;
  163.             fprintf(stderr, "TBuf_Open: couldn't create %s",
  164.                 fullPath);
  165.             return T_BUFFAILED;
  166.         }
  167.         } else {
  168.         *tBufStreamPtr = -1;
  169.         return T_SUCCESS;
  170.         }
  171.     } else {
  172.         syserr = errno;
  173.         fprintf(stderr, "Tbuf_Open: failed to open %s: %d",
  174.             fullPath, syserr);
  175.         return T_BUFFAILED;
  176.     }
  177.     }
  178.  
  179.     if (tHdrStreamPtr == (int *)NULL) {
  180.     return T_SUCCESS;
  181.     }
  182.  
  183.     sprintf(fullPath+pathLen, "thdr.%d%c", tBufId, '\0');
  184.     if ((*tHdrStreamPtr=open(fullPath, mode, 0)) < 0) {
  185.     /*
  186.      * File doesn't exist; we have to make it
  187.      */
  188.     if (errno == ENOENT) {
  189.         if ((*tHdrStreamPtr=open(fullPath, mode+O_CREAT, 0600)) < 0) {
  190.         syserr = errno;
  191.         fprintf(stderr, "TBuf_Open: couldn't create %s",
  192.             fullPath);
  193.         return T_BUFFAILED;        
  194.         }
  195.     } else {
  196.         syserr = errno;
  197.         fprintf(stderr, "Tbuf_Open: failed to open %s: %d",
  198.             fullPath, syserr);
  199.         return T_BUFFAILED;
  200.     }
  201.     }
  202.  
  203.     return T_SUCCESS;
  204. }
  205.  
  206.  
  207. /*
  208.  *----------------------------------------------------------------------
  209.  *
  210.  * TBuf_Seek --
  211.  *
  212.  *    Seek to end minus 2 dummy blocks that tar requires.
  213.  *
  214.  * Results:
  215.  *    None.
  216.  *
  217.  * Side effects:
  218.  *    None.
  219.  *
  220.  *----------------------------------------------------------------------
  221.  */
  222.  
  223. int
  224. TBuf_Seek(tBufStream, len)
  225.     int tBufStream;           /* output file descriptor */
  226.     int len;                  /* length of file */
  227. {
  228.     int retCode;
  229.  
  230.     retCode = (int)lseek(tBufStream, (off_t)len, L_SET);
  231.     syserr = errno;
  232.     return (retCode == -1) ? T_INDXFAILED : T_SUCCESS;
  233. }
  234.  
  235.  
  236. /*
  237.  *----------------------------------------------------------------------
  238.  *
  239.  * TBuf_Close --
  240.  *
  241.  *    Close Tape buffer.
  242.  *
  243.  * Results:
  244.  *    None.
  245.  *
  246.  * Side effects:
  247.  *    None.
  248.  *
  249.  *----------------------------------------------------------------------
  250.  */
  251.  
  252. int
  253. TBuf_Close(tBufStream, tHdrStream, tBufSize)
  254.     int tBufStream;           /* output file descriptor */
  255.     int tHdrStream;           /* output header descriptor */
  256.     int tBufSize;             /* for appending null tar records */
  257. {
  258.     int pad = 0;
  259.  
  260.     if (tBufSize >= 0) {
  261.     pad = TBuf_Terminate(tBufStream, tBufSize);
  262.     fsync(tBufStream);
  263.     }
  264.     close(tBufStream);
  265.  
  266.     if (tHdrStream != -1) {
  267.     if (tBufSize >= 0) {
  268.         fsync(tHdrStream);
  269.     }
  270.     close(tHdrStream);
  271.     }
  272.  
  273.     return pad;
  274.  
  275. }
  276.  
  277.  
  278. /*
  279.  *----------------------------------------------------------------------
  280.  *
  281.  * TBuf_Terminate --
  282.  *
  283.  *    Append final blocks onto end of file to satisfy tar.
  284.  *
  285.  * Results:
  286.  *    None.
  287.  *
  288.  * Side effects:
  289.  *    None.
  290.  *
  291.  *----------------------------------------------------------------------
  292.  */
  293.  
  294. int
  295. TBuf_Terminate(tBufStream, curSize)
  296.     int tBufStream;           /* output file descriptor */
  297.     int curSize;              /* current size in bytes */
  298. {
  299.     char null = '\0';
  300.     char nullBuf[2*T_TBLOCK]; /* tar requires exactly 2 null blocks */
  301.  
  302.     strncpy(nullBuf, &null, sizeof(nullBuf));
  303.  
  304.     if (write(tBufStream, nullBuf, sizeof(nullBuf)) < 1) {
  305.         syserr = errno;
  306.         return -1;
  307.     }
  308.  
  309.     return sizeof(nullBuf);
  310. }
  311.  
  312.  
  313.  
  314. /*
  315.  *----------------------------------------------------------------------
  316.  *
  317.  * TBuf_WriteTarHdr --
  318.  *
  319.  *    Build a tbuf header in tar format.
  320.  *
  321.  * Results:
  322.  *    None.
  323.  *
  324.  * Side effects:
  325.  *    None.
  326.  *
  327.  *----------------------------------------------------------------------
  328.  */
  329.  
  330. int
  331. TBuf_WriteTarHdr(destStream, hdrPtr)
  332.     int destStream;           /* destination */
  333.     T_FileStat *hdrPtr;       /* source info structure */
  334. {
  335.     char null = '\0';
  336.     unsigned char *outPtr;
  337.     unsigned char outBuf[T_TBLOCK];
  338.     THdr *fmtBuf = (THdr *)outBuf;
  339.     char *slashPtr;
  340.     int fileNameLen;
  341.     int sum;
  342.     int i;
  343.     int devmajor;
  344.     int devminor;
  345.     char linkFlag;
  346.  
  347.     strncpy(outBuf, &null, T_TBLOCK);
  348.  
  349.     /*
  350.      * if the name doesn't fit in the regular NAMSIZ space
  351.      * then we have to go to extended format. This means putting
  352.      * the simple filename in the NAMSIZ slot and the preceding part
  353.      * of the pathname in the prefix slot.  Sure hope you have a POSIX
  354.      * compliant tar program that understands this format.
  355.      */
  356.     fileNameLen = strlen(hdrPtr->fileName);
  357.     if (fileNameLen > NAMSIZ) {
  358.     slashPtr = hdrPtr->fileName+NAMSIZ-1;
  359.     while ((*slashPtr != '/') && (slashPtr > hdrPtr->fileName)) {
  360.         slashPtr--;
  361.     }
  362.     if (slashPtr == hdrPtr->fileName) {
  363.         return 0;
  364.     }
  365.     strncpy(fmtBuf->name, slashPtr+1, NAMSIZ);
  366.     strncpy(fmtBuf->prefix, hdrPtr->fileName, slashPtr-hdrPtr->fileName);
  367.     } else {
  368.     strncpy(fmtBuf->name, hdrPtr->fileName, NAMSIZ);
  369.     }
  370.  
  371.     switch (hdrPtr->mode & S_IFMT) {
  372.     case S_IFREG:
  373.     if (*hdrPtr->linkName) {
  374.         linkFlag = LF_LINK;
  375.     } else {
  376.         linkFlag = LF_NORMAL;
  377.     }
  378.     break;
  379.     case S_IFDIR:
  380.     linkFlag = LF_DIR;
  381.     break;
  382.     case S_IFCHR:
  383.     linkFlag = LF_CHR;
  384.     devmajor = (hdrPtr->rdev>>8) & 0xFF;
  385.     devminor = (hdrPtr->rdev) & 0xFF;
  386.     sprintf(fmtBuf->devmajor, "%6o %c%6o %c",
  387.         devmajor, null,    devminor, null);
  388.     break;
  389.     case S_IFBLK:
  390.     linkFlag = LF_BLK;
  391.     devmajor = (hdrPtr->rdev>>8) & 0xFF;
  392.     devminor = (hdrPtr->rdev) & 0xFF;
  393.     sprintf(fmtBuf->devmajor, "%6o %c%6o %c",
  394.         devmajor, null,    devminor, null);
  395.     break;
  396.     case S_IFLNK:
  397.     linkFlag = LF_SYMLINK;
  398.     break;
  399.     case S_IFIFO:
  400.     linkFlag = LF_FIFO;
  401.     break;
  402.     case S_IFRLNK:
  403.     linkFlag = LF_RMTLINK;
  404.     break;
  405.     default:
  406.     linkFlag = LF_NORMAL;
  407.     fprintf(stderr,"TBuf_WriteTarHdr: %s: unexpected file type 0%o\n", 
  408.         hdrPtr->fileName, hdrPtr->mode & S_IFMT);
  409.     break;
  410.     }
  411.  
  412.     sprintf(outBuf+NAMSIZ, "%6o %c%6o %c%6o %c%11o %11o %8s%c%s",
  413.         hdrPtr->mode & (~S_IFMT), null,
  414.         hdrPtr->uid, null,
  415.         hdrPtr->gid, null,
  416.         hdrPtr->size,
  417.         hdrPtr->mtime,
  418.         " ",
  419.         linkFlag,
  420.         "        ");
  421.  
  422.     strncpy(fmtBuf->linkname, hdrPtr->linkName, NAMSIZ);
  423.     strncpy(fmtBuf->magic, TMAGIC, sizeof(TMAGIC));
  424.     strncpy(fmtBuf->uname, hdrPtr->uname, TUNMLEN);
  425.     strncpy(fmtBuf->gname, hdrPtr->gname, TGNMLEN);
  426.  
  427.     for (sum=0,i=0,outPtr=outBuf; i<T_TBLOCK; i++) {
  428.     sum += (int)*outPtr++;
  429.     }
  430.     sprintf(fmtBuf->chksum, "%6o", sum);
  431.  
  432.     write(destStream, outBuf, T_TBLOCK);
  433.  
  434.     return T_TBLOCK;
  435. }
  436.  
  437.  
  438. /*
  439.  *----------------------------------------------------------------------
  440.  *
  441.  * TBuf_ParseTarHdr --
  442.  *
  443.  *    Read a formatted header into pieces.
  444.  *
  445.  * Results:
  446.  *    None.
  447.  *
  448.  * Side effects:
  449.  *    None.
  450.  *
  451.  *----------------------------------------------------------------------
  452.  */
  453.  
  454. int
  455. TBuf_ParseTarHdr(inBuf, statInfoPtr)
  456.     char *inBuf;              /* source buffer of formatted hdr */
  457.     T_FileStat *statInfoPtr;       /* destination info structure */
  458. {
  459.     THdr *fmtBuf = (THdr *)inBuf;
  460.     int sum;
  461.     int chksum;
  462.     int i;
  463.     int devmajor;
  464.     int devminor;
  465.     char tmpPrefix[PRFXLEN+1];
  466.     char saveChar;
  467.  
  468.     sscanf(fmtBuf->chksum, "%o", &chksum);
  469.     strncpy(fmtBuf->chksum, "        ", sizeof(fmtBuf->chksum));
  470.     for (sum=0,i=0; i<sizeof(THdr); i++) {
  471.     sum += (int)*inBuf++;
  472.     }
  473.     if (sum != chksum) {
  474.     fprintf(stderr,"Checksum failed for file %s: read %d, actual %d\n",
  475.         fmtBuf->name, chksum, sum);
  476.     return T_BUFFAILED;
  477.     }
  478.  
  479.     /*
  480.      * The name and prefix fields must be combined.
  481.      * Furthermore, there's no guarantee that they're null-terminated,
  482.      * but uname and gname are.
  483.      */
  484.     if (*fmtBuf->prefix) {
  485.     strncpy(tmpPrefix, fmtBuf->prefix, PRFXLEN);
  486.     saveChar = *(fmtBuf->name+NAMSIZ);
  487.     *(fmtBuf->name+NAMSIZ) = '\0';
  488.     statInfoPtr->fileName = Str_Cat(3, tmpPrefix, "/", fmtBuf->name);
  489.     *(fmtBuf->name+NAMSIZ) = saveChar;    
  490.     } else {
  491.     saveChar = *(fmtBuf->name+NAMSIZ);
  492.     *(fmtBuf->name+NAMSIZ) = '\0';
  493.     statInfoPtr->fileName = Str_Dup(fmtBuf->name);
  494.     *(fmtBuf->name+NAMSIZ) = saveChar;    
  495.     }
  496.     sscanf(fmtBuf->mode, "%o", &statInfoPtr->mode);
  497.     sscanf(fmtBuf->uid, "%o", &statInfoPtr->uid);
  498.     sscanf(fmtBuf->gid, "%o", &statInfoPtr->gid);
  499.     sscanf(fmtBuf->size, "%o", &statInfoPtr->size);
  500.     sscanf(fmtBuf->mtime, "%o", &statInfoPtr->mtime);
  501.     statInfoPtr->rdev = 0;
  502.  
  503.     switch (fmtBuf->linkflag) {
  504.     case LF_NORMAL:
  505.     statInfoPtr->mode |= S_IFREG;
  506.     break;
  507.     case LF_DIR:
  508.     statInfoPtr->mode |= S_IFDIR;
  509.     break;
  510.     case LF_CHR:
  511.     statInfoPtr->mode |= S_IFCHR;
  512.     sscanf(fmtBuf->devmajor, "%o", &devmajor);
  513.     sscanf(fmtBuf->devminor, "%o", &devminor);
  514.     statInfoPtr->rdev = (devmajor<<8) | devminor;
  515.     break;
  516.     case LF_BLK:
  517.     statInfoPtr->mode |= S_IFBLK;
  518.     sscanf(fmtBuf->devmajor, "%o", &devmajor);
  519.     sscanf(fmtBuf->devminor, "%o", &devminor);
  520.     statInfoPtr->rdev = (devmajor<<8) | devminor;
  521.     break;
  522.     case LF_SYMLINK:
  523.     statInfoPtr->mode |= S_IFLNK;
  524.     break;
  525.     case LF_FIFO:
  526.     statInfoPtr->mode |= S_IFIFO;
  527.     break;
  528.     case LF_RMTLINK:
  529.     statInfoPtr->mode |= S_IFRLNK;
  530.     break;
  531.     default:
  532.     fprintf(stderr,"ParseTarHdr: unknown file type: '%c'\n", fmtBuf->linkflag);
  533.     statInfoPtr->mode |= S_IFREG;
  534.     break;
  535.     }
  536.     saveChar = *(fmtBuf->linkname+NAMSIZ);
  537.     *(fmtBuf->linkname+NAMSIZ) = '\0';
  538.     statInfoPtr->linkName = Str_Dup(fmtBuf->linkname);
  539.     *(fmtBuf->linkname+NAMSIZ) = saveChar;
  540.     statInfoPtr->uname = Str_Dup(fmtBuf->uname);
  541.     statInfoPtr->gname = Str_Dup(fmtBuf->gname);
  542.  
  543.     return T_SUCCESS;
  544. }
  545.  
  546.  
  547. /*
  548.  *----------------------------------------------------------------------
  549.  *
  550.  * TBuf_FindFile --
  551.  *
  552.  *    Locate a file by scanning through tbuf
  553.  *
  554.  * Results:
  555.  *    None.
  556.  *
  557.  * Side effects:
  558.  *    Leaves the file pointer positioned to read the data.
  559.  *
  560.  *----------------------------------------------------------------------
  561.  */
  562.  
  563. int
  564. TBuf_FindFile(tBufStream, statInfoPtr)
  565.     int tBufStream;           /* open tbuf descriptor */
  566.     T_FileStat *statInfoPtr;  /* file to be located */
  567. {
  568.     char *fileName = statInfoPtr->fileName;
  569.     int offset = statInfoPtr->offset;
  570.     char buf[T_TBLOCK];
  571.     T_FileStat tmpStatInfo;
  572.     int retCode = T_SUCCESS;
  573.  
  574.     if (jDebug) {
  575.     fprintf(stderr,"FindFile: %d %s\n", offset, fileName);
  576.     }
  577.  
  578.     /* seek to beginning of file in buffer */
  579.     if (TBuf_Seek(tBufStream, offset) != T_SUCCESS) {
  580.     fprintf(stderr,"FindFile: seek %d errno %d\n", offset, errno);
  581.     return T_BUFFAILED;
  582.     }
  583.  
  584.     /* get a tar hdr */
  585.     if (read(tBufStream, buf, sizeof(buf)) != sizeof(buf)) {
  586.     fprintf(stderr,"FindFile: read errno %d\n", errno);
  587.     return T_BUFFAILED;
  588.     }
  589.  
  590.     /* now see if we got a tar hdr */
  591.     if ((retCode=TBuf_ParseTarHdr(buf, &tmpStatInfo)) != T_SUCCESS) {
  592.     if (jDebug) {
  593.         fprintf(stderr,"FindFile: bad tar hdr\n");
  594.     }
  595.     return retCode;
  596.     }
  597.  
  598.     /* sanity check: filename better match */
  599.     if (strcmp(fileName, tmpStatInfo.fileName) != 0) {
  600.     if (jDebug) {
  601.         fprintf(stderr,"FindFile: %s != %s\n",
  602.             fileName, tmpStatInfo.fileName);
  603.     }
  604.     return T_BUFFAILED;
  605.     }
  606.  
  607.     /* we don't have these in the index so we need to get them here */
  608.     statInfoPtr->gid = tmpStatInfo.gid;
  609.     statInfoPtr->uid = tmpStatInfo.uid;
  610.  
  611.     return T_SUCCESS;
  612. }
  613.  
  614.  
  615.  
  616. /*
  617.  *----------------------------------------------------------------------
  618.  *
  619.  * TBuf_Delete --
  620.  *
  621.  *    Delete a sequence of tape buffers
  622.  *
  623.  * Results:
  624.  *    return code
  625.  *
  626.  * Side effects:
  627.  *    buffer is destroyed.
  628.  *
  629.  * Note:
  630.  *      This is a hack. No guarantee that space is actually
  631.  *      freed after we remove the tbuf; someone might be using it.
  632.  *
  633.  *----------------------------------------------------------------------
  634.  */
  635.  
  636. int
  637. TBuf_Delete(rootPath, arch, firstTBuf, lastTBuf)
  638.     char *rootPath;           /* path to this archive */
  639.     char *arch;               /* archive name */
  640.     int firstTBuf;            /* low number tbuf */
  641.     int lastTBuf;             /* high number tbuf */
  642. {
  643.     char fullPath[T_MAXPATHLEN];
  644.     int tBufId;
  645.  
  646.     if (firstTBuf == -1) {
  647.     if (Admin_RemoveLRU(rootPath, arch, &firstTBuf) != T_SUCCESS) {
  648.         return T_FAILURE;
  649.     }
  650.     lastTBuf = firstTBuf;
  651.     }
  652.  
  653.     for (tBufId=firstTBuf; tBufId<=lastTBuf; tBufId++) {
  654.         sprintf(fullPath, "%s/%s/tbuf.%d", rootPath, arch, tBufId);
  655.         unlink(fullPath);
  656.         sprintf(fullPath, "%s/%s/thdr.%d", rootPath, arch, tBufId);
  657.         unlink(fullPath);
  658.         sprintf(fullPath, "%s/%s/meta.%d", rootPath, arch, tBufId);
  659.         unlink(fullPath);
  660.     }
  661.  
  662.     return T_SUCCESS;
  663. }
  664.